var websocket = require('net.iamyellow.tiws').createWS();

var _base_url = "";
var trans_url = "";
var that = null;

var SockJS = function(url) {
	var utils = {};
	utils.random_number = function(max) {
    	return Math.floor(Math.random() * max);
	};
	
	utils.random_number_string = function(max) {
	    var t = (''+(max - 1)).length;
	    var p = Array(t+1).join('0');
	    return (p + utils.random_number(max)).slice(-t);
	};

	function onopen() {
		alert("implement onopen!");
	}
	function onerror(ev) {
		alert("implement onerror: " + ev.error);
	}
	function onmessage() {
		alert("implement onmessage!");
	}
	function onclose() {
		alert("implement onclose!");
	}
	var random_string_chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';
	utils.random_string = function(length, max) {
	    max = max || random_string_chars.length;
	    var i, ret = [];
	    for(i=0; i < length; i++) {
	        ret.push( random_string_chars.substr(Math.floor(Math.random() * max),1) );
	    }
	    return ret.join('');
	};


	// This may be quite slow, so let's delay until user actually uses bad
	// characters.
	var unroll_lookup = function(escapable) {
	    var i;
	    var unrolled = {};
	    var c = [];
	    for(i=0; i<65536; i++) {
	        c.push( String.fromCharCode(i) );
	    }
	    escapable.lastIndex = 0;
	    c.join('').replace(escapable, function (a) {
	        unrolled[ a ] = '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
	        return '';
	    });
	    escapable.lastIndex = 0;
	    return unrolled;
	};
	
	
	// Quote string, also taking care of unicode characters that browsers
	// often break. Especially, take care of unicode surrogates:
	//    http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates
	utils.quote = function(string) {
	    var quoted = JSON.stringify(string);
	
	    // In most cases this should be very fast and good enough.
	    extra_escapable.lastIndex = 0;
	    if(!extra_escapable.test(quoted)) {
	        return quoted;
	    }
	
	    if(!extra_lookup) extra_lookup = unroll_lookup(extra_escapable);
	
	    return quoted.replace(extra_escapable, function(a) {
	        return extra_lookup[a];
	    });
	};
	
	
	// JSON Quote string. Use native implementation when possible.
	// var JSONQuote = (JSON && JSON.stringify) || function(string) {
	    // json_escapable.lastIndex = 0;
	    // if (json_escapable.test(string)) {
	        // string = string.replace(json_escapable, function(a) {
	            // return json_lookup[a];
	        // });
	    // }
	    // return '"' + string + '"';
	// };
	
	// Chars worth escaping, as defined by Douglas Crockford:
	//   https://github.com/douglascrockford/JSON-js/blob/47a9882cddeb1e8529e07af9736218075372b8ac/json2.js#L196
	var json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
	    json_lookup = {
	"\u0000":"\\u0000","\u0001":"\\u0001","\u0002":"\\u0002","\u0003":"\\u0003",
	"\u0004":"\\u0004","\u0005":"\\u0005","\u0006":"\\u0006","\u0007":"\\u0007",
	"\b":"\\b","\t":"\\t","\n":"\\n","\u000b":"\\u000b","\f":"\\f","\r":"\\r",
	"\u000e":"\\u000e","\u000f":"\\u000f","\u0010":"\\u0010","\u0011":"\\u0011",
	"\u0012":"\\u0012","\u0013":"\\u0013","\u0014":"\\u0014","\u0015":"\\u0015",
	"\u0016":"\\u0016","\u0017":"\\u0017","\u0018":"\\u0018","\u0019":"\\u0019",
	"\u001a":"\\u001a","\u001b":"\\u001b","\u001c":"\\u001c","\u001d":"\\u001d",
	"\u001e":"\\u001e","\u001f":"\\u001f","\"":"\\\"","\\":"\\\\",
	"\u007f":"\\u007f","\u0080":"\\u0080","\u0081":"\\u0081","\u0082":"\\u0082",
	"\u0083":"\\u0083","\u0084":"\\u0084","\u0085":"\\u0085","\u0086":"\\u0086",
	"\u0087":"\\u0087","\u0088":"\\u0088","\u0089":"\\u0089","\u008a":"\\u008a",
	"\u008b":"\\u008b","\u008c":"\\u008c","\u008d":"\\u008d","\u008e":"\\u008e",
	"\u008f":"\\u008f","\u0090":"\\u0090","\u0091":"\\u0091","\u0092":"\\u0092",
	"\u0093":"\\u0093","\u0094":"\\u0094","\u0095":"\\u0095","\u0096":"\\u0096",
	"\u0097":"\\u0097","\u0098":"\\u0098","\u0099":"\\u0099","\u009a":"\\u009a",
	"\u009b":"\\u009b","\u009c":"\\u009c","\u009d":"\\u009d","\u009e":"\\u009e",
	"\u009f":"\\u009f","\u00ad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601",
	"\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f",
	"\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d",
	"\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029",
	"\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d",
	"\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061",
	"\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065",
	"\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069",
	"\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d",
	"\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0",
	"\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4",
	"\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8",
	"\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc",
	"\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"};
	
	// Some extra characters that Chrome gets wrong, and substitutes with
	// something else on the wire.
	var extra_escapable = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,
	    extra_lookup;


	_base_url = url;
	var _server = utils.random_number_string(1000);
    var connid = utils.random_string(8);
    trans_url = _base_url + '/' + _server + '/' + connid + '/websocket';
	Ti.API.info( "websocket @ :" + trans_url);
	

	function connect() {
	    that = this;
		websocket.addEventListener('open', onopen);
		websocket.addEventListener('error', onerror); 
		websocket.addEventListener('message', _didMessage);
		websocket.addEventListener('close', onclose);
		Ti.API.info("opening: " + trans_url);
		websocket.open(trans_url);
	}
	
	function send(msg) {
		websocket.send('[' + utils.quote(msg) + ']');
	}
	
	function _didMessage(evt) {
		var data = evt.data;
	    var type = data.slice(0, 1);
	    switch(type) {
	    case 'o':
	        Ti.API.info("open!");
	        break;
	    case 'a':
	        var payload = JSON.parse(data.slice(1) || '[]');
	        for(var i=0; i < payload.length; i++){
	            that.processMessage(payload[i]);
	        }
	        break;
	    case 'm':
	        var payload = JSON.parse(data.slice(1) || 'null');
	        that.processMessage(payload);
	        break;
	    case 'c':
	        var payload = JSON.parse(data.slice(1) || '[]');
	        that.onclose(payload[0], payload[1]);
	        break;
	    case 'h':
	        //that._dispatchHeartbeat();
	        break;
	    }
	}
	
	function setOnopen(f) {
		onopen = f;
	}
	
	function setOnmessage(f) {
		onmessage = f;
	}
	
	function setOnclose(f) {
		onclose = f;
	}
	
	function processMessage(data) {
		onmessage( { event:"message",  data: data } );
	}
	
	return {
		connect : connect,
		setOnopen : setOnopen,
		setOnmessage : setOnmessage,
		setOnclose : setOnclose,
		send : send,
		onopen : onopen,
		onclose : onclose,
		onmessage : onmessage,
		processMessage : processMessage
	};
};
module.exports = SockJS;
